package org.metasketch.graphics.language.validator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.metasketch.graphics.language.xml.GraphicNotation;
import org.metasketch.graphics.language.xml.NamedEntity;
import org.metasketch.graphics.language.xml.RichEntity;
import org.metasketch.reflection.RefUtil;
import org.metasketch.reflection.ReflectionAnalyser;

public class ValueChecker {

	static RefUtil rutil = new RefUtil();

	static Map<Class, List<String>> optionalFields = new HashMap<Class, List<String>>();
	static Map<Class, List<String>> javaBeanFields = new HashMap<Class, List<String>>();

	public static void check(RichEntity entity, Messaging messaging)
			throws Throwable {

		List constants = entity.getConstants();
		check(constants, messaging);

		List images = entity.getImages();
		check(images, messaging);

		List styles = entity.getStyles();
		check(styles, messaging);

		List slots = entity.getSlots();
		check(slots, messaging);

		List bindings = entity.getBindings();
		check(bindings, messaging);

		// missing test graphics and child collections

	}

	public static void addOptionalField(Class type, String fieldname) {

		List<String> fieldNames = optionalFields.get(type);
		if (fieldNames == null) {
			fieldNames = new ArrayList<String>();
			optionalFields.put(type, fieldNames);
			fieldNames.add(fieldname);
		} else {
			if (!fieldNames.contains(fieldname))
				fieldNames.add(fieldname);
		}

	}

	public static void check(List objects, Messaging messaging)
			throws Throwable {
		for (Object object : objects) {
			check(object, messaging);
		}
	}

	public static void check(Object obj, Messaging messaging) throws Throwable {
		
		ReflectionAnalyser.getJavaBeanFieldNames(obj.getClass());
		
		List<String> fieldNames = optionalFields.get(obj.getClass());

		if (fieldNames == null)
			return;

		for (String fieldname : fieldNames) {
			Object value = rutil.getValue(obj, fieldname);

			if (value == null) {

				String name = "";

				if (obj instanceof NamedEntity) {
					name = " named '" + ((NamedEntity) obj).getName() + "' ";
				}

				messaging.addError("Null value for '" + fieldname
						+ "' in type '" + obj.getClass().getSimpleName() + "' "
						+ name + ". Need to define a value !");
			}

		}

	}

}
